package com.iot.sdk.service.impl;

import com.dc3.common.bean.driver.AttributeInfo;
import com.dc3.common.bean.point.PointValue;
import com.dc3.common.model.Device;
import com.iot.sdk.bean.driver.DriverContext;
import com.iot.sdk.service.DriverCommandService;
import com.iot.sdk.service.DriverCustomService;
import com.iot.sdk.service.DriverService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author 咕唧
 * @Date 2022/7/25 20:00
 * @Version 1.0
 */
@Service
public class DriverCommandServiceImpl implements DriverCommandService {

    private DriverContext driverContext;

    private DriverService driverService;

    private DriverCustomService driverCustomService;

    @Autowired
    public void setDriverCustomService(DriverCustomService driverCustomService) {
        this.driverCustomService = driverCustomService;
    }

    @Autowired
    public void setDriverService(DriverService driverService) {
        this.driverService = driverService;
    }

    @Autowired
    public void setDriverContext(DriverContext driverContext) {
        this.driverContext = driverContext;
    }

    @Override
    public PointValue read(String deviceId, String pointId) {
        //根据设备id获取到设备数据
        Device device = driverContext.getDeviceByDeviceId(deviceId);
        //这里只定义一个规范，具体怎么实现交给驱动去做
        try {
            String rawString = driverCustomService.read(driverContext.getDriverInfoByDeviceId(deviceId)
                    , driverContext.getPointInfoByDeviceIdAndPointId(deviceId, pointId)
                    , device
                    , driverContext.getPointByDeviceIdAndPointId(deviceId, pointId));
            //创建一个位号数据,里面保存了设备的id,位号的id,原始的数据,和处理后的数据
            //这个位号数据需要格式化处理,为什么呢? 比如我们的mqtt中有一个qos,是一个数字,代表不同的消息的发送类型,但是我们现在查询到的是一个字符串
            //所以我们需要对他进行转换,转成对应的类型,不然我们在调用方法时候会提示错误,特别是类型转换异常
            //还有一种情况,就是我们为了方便统一代码,减少复杂的逻辑,我们会将所有的数据都以字符串的方式进行操作,但是你传递过来的这个字符串或者这个数据格式可能不符合我我们的要求
            //所以我们还需要进行转换一下,还有一些可能,你传递的数据期望是一个数字,但是可以写字符串,但是这个字符串本身其实应该是数字,可能会存在范围要求
            //转换的时候可以进行范围的判断
            PointValue pointValue = new PointValue(deviceId, pointId, rawString, driverService.convertValue(deviceId, pointId, rawString));

            return pointValue;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Boolean write(String deviceId, String pointId, String value) {
        Device device = driverContext.getDeviceByDeviceId(deviceId);

        try {
            return driverCustomService.write(driverContext.getDriverInfoByDeviceId(deviceId)
                    , driverContext.getPointInfoByDeviceIdAndPointId(deviceId, pointId)
                    , device
                    , new AttributeInfo(value, driverContext.getPointByDeviceIdAndPointId(deviceId, pointId).getType()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
